﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Linq;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Script.Serialization;
using WW.NActiveRecord.ContractExceptions;
using WW.NActiveRecord.Internal.Utils;

namespace WW.NActiveRecord{
    /// <summary>
    /// 数据库表和活动记录对象的映射集合
    /// </summary>
    public class Record :IDictionary<string,object>
    {
        readonly Dictionary<string, object> record = new Dictionary<string, object>(CaseInsensitiveComparer2.Default);
        static readonly JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
        static readonly Regex jsonRegex = new Regex("\"(\\w*)\":", RegexOptions.IgnoreCase);

        internal Record(){}

        public override string ToString(){
            return jsonRegex.Replace(jsonSerializer.Serialize(record), "${1}:").Replace("\"", "'");
        }
        
        public int Count {
            get { return record.Count; }
        }
        public void Clear() {
            record.Clear();
        }
        ICollection<string> IDictionary<string, object>.Keys {
            get { return record.Keys; }
        }

        ICollection<object> IDictionary<string, object>.Values {
            get { return record.Values; }
        }
        public bool Contains(string name) {
            return record.ContainsKey(name);
        }

        public object this[string name] {
            get {
                if (!record.ContainsKey(name)) {
                    throw new MissingColumnException(name);
                }
                return record[name];
            }
            set { record[name] = value; }
        }

        internal TConvertTo GetValueAndConvertTo<TConvertTo>(string name){
            return (TConvertTo)GetValueAndConvertTo(typeof(TConvertTo), name);
        }

        internal object GetValueAndConvertTo(Type convertTo, string name) {
            //Debug.Assert(Contains(name),"没找到:key="+name);
            return DBConvert.ChangeType(this[name], convertTo);
        }

        public IEnumerable<string> Names {
            get { return record.Keys; }
        } 



        public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
        {
            return record.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
        {
            record.Add(item.Key,item.Value);
        }

        bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
        {
            return AsICollection.Contains(item);
        }

        private ICollection<KeyValuePair<string, object>> AsICollection
        {
            get { return record; }
        }

        void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
        {
            AsICollection.CopyTo(array,arrayIndex);
        }

        bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
        {
            return AsICollection.Remove(item);
        }

        
        bool ICollection<KeyValuePair<string, object>>.IsReadOnly
        {
            get { return AsICollection.IsReadOnly; }
        }

        bool IDictionary<string, object>.ContainsKey(string name)
        {
            return record.ContainsKey(name);
        }

        void IDictionary<string, object>.Add(string name, object value)
        {
            record.Add(name,value);
        }

        bool IDictionary<string, object>.Remove(string name)
        {
            return record.Remove(name);
        }

        bool IDictionary<string, object>.TryGetValue(string name, out object value)
        {
            return record.TryGetValue(name,out value);
        }
    }
}